/*
 * led.h
 *
 *  Created on: 03.11.2011
 *      Author: g.kruglov
 */

#ifndef LED_H_
#define LED_H_

#include "stm32f10x.h"
#include "ch.h"
#include "hal.h"
#include "kl_lib_f100.h"


#define LED_TIM_RCC         rccEnableTIM4();
#define CCER_SETTINGS     ( TIM_CCER_CC1E | \
                            TIM_CCER_CC1P | \
                            TIM_CCER_CC2E | \
                            TIM_CCER_CC2P | \
                            TIM_CCER_CC3E | \
                            TIM_CCER_CC3P | \
                            TIM_CCER_CC4E | \
                            TIM_CCER_CC4P )


#define clMax     	    255
#define clMin		    0
#define clThreshold     50

// Channels
struct Channels_t {
    uint8_t North, South, West, East;
    bool operator == (const Channels_t AChannels)   { return ((North == AChannels.North) and (South == AChannels.South) and (West == AChannels.West) and (East == AChannels.East)); }
    bool operator <  (const uint8_t AValue)         { return ((North < AValue) and (South < AValue) and (West < AValue) and (East < AValue));                                       }
};

#define chOff   ((Channels_t) {0, 0, 0, 0}          )
#define chN     ((Channels_t) {255, 0, 0, 0}        )
#define chN_chW ((Channels_t) {255, 0, 255, 0}      )
#define chS     ((Channels_t) {0, 255, 0, 0}        )
#define chS_chE ((Channels_t) {0, 255, 0, 255}      )
#define chW     ((Channels_t) {0, 0, 255, 0}        )
#define chE     ((Channels_t) {0, 0, 0, 255}        )
#define chOn    ((Channels_t) {255, 255, 255, 255}  )

/*
 * 4 channels leds
 * Provides smooth bright change.
 */
#define LED_SETUP_DELAY_SHORT_MS    12
#define LED_SETUP_DELAY_LONG_MS     28

#define LED_TIM         TIM4
#define LED_1_CH		CCR1
#define LED_2_CH     	CCR3
#define LED_3_CH   		CCR4
#define LED_4_CH    	CCR2
#define LED_RCC_EN()    rccEnableTIM4()

class Led4Ch_t {
private:
    Channels_t INeededBright;
	Thread *PThread;
	bool IsSleeping;
	uint8_t SleepTime;
	void ISetN(uint8_t AValue)  {LED_TIM->LED_1_CH   = AValue;}
	void ISetS(uint8_t AValue)  {LED_TIM->LED_2_CH 	= AValue;}
	void ISetW(uint8_t AValue)  {LED_TIM->LED_3_CH  	= AValue;}
	void ISetE(uint8_t AValue)  {LED_TIM->LED_4_CH  	= AValue;}
	void IOinit()               { PinSetupAlterFuncOutput(GPIOB, 6, omPushPull); PinSetupAlterFuncOutput(GPIOB, 7, omPushPull); PinSetupAlterFuncOutput(GPIOB, 8, omPushPull); PinSetupAlterFuncOutput(GPIOB, 9, omPushPull); }
public:
	Channels_t ICurrentBright;
	void Init();
	void Task();
	void SetBright(Channels_t ABright) {
		ISetN(ABright.North);
		ISetW(ABright.West);
		ISetE(ABright.East);
		ISetS(ABright.South);
		ICurrentBright = ABright;
	}
	void SetBrightSmoothly(Channels_t ABright);
//	bool IsOff() { return (ICurrentBright == INeededBright) and (ICurrentBright == clMin); }
//	void Blink(uint32_t ABlinkDelay, Color_t AColor) {
//	        IsInsideBlink = true;
//	        IBlinkDelay = ABlinkDelay;
//	        INeededColor = AColor;
//	        SetColor(AColor);
//	        Delay.Reset(&ITimer);
//	    }
};

extern Led4Ch_t Led;


#endif /* LED_H_ */
